package com.jxtc.enterprise.admin.service;

import cn.hutool.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jxtc.enterprise.admin.dto.AdminLoginDTO;
import com.jxtc.enterprise.admin.vo.AdminLoginSuccessVO;
import com.jxtc.enterprise.common.entity.Admin;
import com.jxtc.enterprise.common.entity.Tenant;
import com.jxtc.enterprise.common.entity.User;
import com.jxtc.enterprise.common.exception.LoginFailureException;
import com.jxtc.enterprise.common.mapper.AdminMapper;
import com.jxtc.enterprise.common.mapper.TenantMapper;
import com.jxtc.enterprise.common.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
@Slf4j
public class AdminLoginService {

    private final UserMapper userMapper;

    private final AdminMapper adminMapper;

    private final TenantMapper tenantMapper;

    private final RedisTemplate<String, Object> redisTemplate;

    @Value("${multiTenant.tokenExpAtDays}")
    private final Integer tokenExpAtDays = 30;

    /**
     * 登录过期时间，单位：毫秒
     */
    public final long LOGIN_EXPIRE_TIME = 1000L * 60 * 60 * 24 * 30;
    /**
     * JWT 加密密钥
     */
    public final String ADMIN_LOGIN_JWT_KEY = "aiyi2SZFDR0P0i6HRODlbhd5wqmhE5HrRhYPePXAmmBRCbluN9lh1xiZJSxtMHUWnw0_vmd3bK-6DQfVyt87bw";

    public AdminLoginSuccessVO login(AdminLoginDTO dto) {
        // User 表中 company_id 和 department_id 为 00000000000000000000000000000000 的代表管理员账户
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone_number", dto.getPhoneNumber());
        wrapper.eq("company_id", "00000000000000000000000000000000");
        wrapper.eq("department_id", "00000000000000000000000000000000");
        wrapper.eq("del_flag", 0);
        wrapper.orderByDesc("create_time");

        // 取最新的数据
        Optional<User> userOptional = userMapper.selectList(wrapper).stream().findFirst();
        if (!userOptional.isPresent()) {
            throw new LoginFailureException("账号不存在");
        }

        User user = userOptional.get();

        // 暂时不加密
        boolean matches = user.getPasswd().equals(dto.getPassword());

        if (matches) {
            String token = JWT.create()
                    .setPayload("name", user.getUsername())
                    .setPayload("role", "admin")
                    .setPayload("userId", user.getId())
                    .setExpiresAt(new Date(System.currentTimeMillis() + LOGIN_EXPIRE_TIME))
                    .setKey(ADMIN_LOGIN_JWT_KEY.getBytes())
                    .sign();
            return new AdminLoginSuccessVO(user.getId(), user.getUsername(), "admin", token);
        }

        throw new LoginFailureException("账号或密码错误");
    }



    public AdminLoginSuccessVO loginV2(AdminLoginDTO dto) {

        // 先判断是否为 admin
        Admin adminVo = adminMapper.selectOne(new LambdaQueryWrapper<Admin>().eq(Admin::getPhone, dto.getPhoneNumber()).eq(Admin::getDelFlag, 0));
        if (adminVo != null && adminVo.getPassword().equalsIgnoreCase(dto.getPassword())) {
            String token = JWT.create()
                    .setPayload("role", "admin")
                    .setPayload("userId", adminVo.getId())
                    .setPayload("name", adminVo.getNickname())
                    .setExpiresAt(new Date(System.currentTimeMillis() + LOGIN_EXPIRE_TIME))
                    .setKey(ADMIN_LOGIN_JWT_KEY.getBytes())
                    .sign();
            // 将token 保存在 redis中，并设置有效期为 30 天; 登录有效期放在 application.properties 中的配置值中
            redisTemplate.opsForValue().set(adminVo.getId(), token, tokenExpAtDays , TimeUnit.DAYS);
            return new AdminLoginSuccessVO(adminVo.getId(), adminVo.getNickname(), "admin", token);
        }
        // 再判断是否是 租户
        Tenant tenant = tenantMapper.selectOne(new LambdaQueryWrapper<Tenant>().eq(Tenant::getPhone, dto.getPhoneNumber()).eq(Tenant::getDelFlag, 0));
        if (tenant != null && tenant.getPassword().equalsIgnoreCase(dto.getPassword())) {
            String token = JWT.create()
                    .setPayload("role", "tenant")
                    .setPayload("userId", tenant.getId())
                    .setPayload("name", tenant.getNickname())
                    .setExpiresAt(new Date(System.currentTimeMillis() + LOGIN_EXPIRE_TIME))
                    .setKey(ADMIN_LOGIN_JWT_KEY.getBytes())
                    .sign();
            // 将token 保存在 redis中，并设置有效期为 30 天; 登录有效期放在 application.properties 中的配置值中
            redisTemplate.opsForValue().set(tenant.getId(), token, tokenExpAtDays , TimeUnit.DAYS);
            return new AdminLoginSuccessVO(tenant.getId(), tenant.getNickname(), "tenant", token);
        }

        throw new LoginFailureException("账号或密码错误");
    }
}
